package com.lifeverse.entity;

import com.lifeverse.entity.enums.DecisionStatus;
import com.lifeverse.entity.enums.DecisionType;
import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 决策实体类
 * 记录生命体的决策信息
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "decisions", indexes = {
    @Index(name = "idx_decision_life_entity", columnList = "life_entity_id"),
    @Index(name = "idx_decision_type", columnList = "type"),
    @Index(name = "idx_decision_status", columnList = "status"),
    @Index(name = "idx_decision_created_at", columnList = "created_at")
})
public class Decision extends BaseEntity {
    
    /**
     * 决策标题
     */
    @Column(name = "title", nullable = false, length = 200)
    private String title;
    
    /**
     * 决策描述
     */
    @Column(name = "description", length = 1000)
    private String description;
    
    /**
     * 决策类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "type", nullable = false, length = 30)
    private DecisionType type;
    
    /**
     * 决策状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 30)
    private DecisionStatus status = DecisionStatus.PENDING;
    
    /**
     * 决策的生命体
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "life_entity_id", nullable = false)
    private LifeEntity lifeEntity;
    
    /**
     * 决策上下文（JSON格式）
     */
    @Column(name = "context", columnDefinition = "TEXT")
    private String context;
    
    /**
     * 决策选项（JSON格式）
     */
    @Column(name = "options", columnDefinition = "TEXT")
    private String options;
    
    /**
     * 选择的决策方案
     */
    @Column(name = "chosen_option", length = 500)
    private String chosenOption;
    
    /**
     * 决策理由
     */
    @Column(name = "reasoning", columnDefinition = "TEXT")
    private String reasoning;
    
    /**
     * 决策置信度（0-1）
     */
    @Column(name = "confidence_score", precision = 5, scale = 4)
    private BigDecimal confidenceScore;
    
    /**
     * 预期影响评分（-100到100）
     */
    @Column(name = "expected_impact", precision = 6, scale = 2)
    private BigDecimal expectedImpact;
    
    /**
     * 实际影响评分（-100到100）
     */
    @Column(name = "actual_impact", precision = 6, scale = 2)
    private BigDecimal actualImpact;
    
    /**
     * 决策开始时间
     */
    @Column(name = "started_at")
    private LocalDateTime startedAt;
    
    /**
     * 决策完成时间
     */
    @Column(name = "completed_at")
    private LocalDateTime completedAt;
    
    /**
     * 决策执行时间
     */
    @Column(name = "executed_at")
    private LocalDateTime executedAt;
    
    /**
     * 决策超时时间
     */
    @Column(name = "timeout_at")
    private LocalDateTime timeoutAt;
    
    /**
     * 决策历史记录
     */
    @OneToMany(mappedBy = "decision", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<DecisionHistory> histories = new ArrayList<>();
    
    /**
     * 决策反馈
     */
    @OneToMany(mappedBy = "decision", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<DecisionFeedback> feedbacks = new ArrayList<>();
    
    /**
     * 开始决策处理
     */
    public void start() {
        this.status = DecisionStatus.ANALYZING;
        this.startedAt = LocalDateTime.now();
    }
    
    /**
     * 完成决策
     */
    public void complete(String chosenOption, String reasoning, BigDecimal confidence) {
        this.status = DecisionStatus.DECIDED;
        this.chosenOption = chosenOption;
        this.reasoning = reasoning;
        this.confidenceScore = confidence;
        this.completedAt = LocalDateTime.now();
    }
    
    /**
     * 执行决策
     */
    public void execute() {
        if (this.status == DecisionStatus.DECIDED) {
            this.status = DecisionStatus.EXECUTING;
            this.executedAt = LocalDateTime.now();
        }
    }
    
    /**
     * 标记决策完成
     */
    public void markCompleted(BigDecimal actualImpact) {
        this.status = DecisionStatus.COMPLETED;
        this.actualImpact = actualImpact;
    }
    
    /**
     * 标记决策失败
     */
    public void markFailed(String reason) {
        this.status = DecisionStatus.FAILED;
        this.reasoning = (this.reasoning != null ? this.reasoning + "\n失败原因: " : "失败原因: ") + reason;
    }
    
    /**
     * 判断是否超时
     */
    public boolean isTimeout() {
        return timeoutAt != null && LocalDateTime.now().isAfter(timeoutAt);
    }
    
    /**
     * 计算决策准确性
     */
    public BigDecimal calculateAccuracy() {
        if (expectedImpact == null || actualImpact == null) {
            return null;
        }
        
        BigDecimal difference = expectedImpact.subtract(actualImpact).abs();
        BigDecimal maxValue = BigDecimal.valueOf(100);
        return maxValue.subtract(difference).max(BigDecimal.ZERO);
    }
}